/**
 * @ Author: luoqi
 * @ Create Time: 2024-04-19 16:56
 * @ Modified by: luoqi
 * @ Modified time: 2025-07-13 00:08
 * @ Description:
 */

#ifndef _YMODEM_H
#define _YMODEM_H

#include <stdint.h>
#include <stddef.h>

typedef enum {
    YMODEM_SOH = 0x01,
    YMODEM_STX = 0x02,
    YMODEM_EOT = 0x04,
    YMODEM_ACK = 0x06,
    YMODEM_NAK = 0x15,
    YMODEM_CAN = 0x18,
    YMODEM_C   = 0x43,
} YModemCode;

typedef enum {
    YMODEM_STAT_STARTING = 0,
    YMODEM_STAT_TRANSMITTING,
    YMODEM_STAT_FINISHING,
    YMODEM_STAT_FINISHED
} YModemStat;

typedef int (*YModemCb)(const uint8_t *, size_t);
typedef int (*YModemPutc)(const uint8_t c);
typedef int (*YModemGetc)(uint8_t *c, size_t timeout_ms);
typedef struct {
    YModemStat stat;
    
    uint16_t datasz;
    uint8_t *buf;
    YModemPutc putc;
    YModemGetc getc;

    uint32_t timeout_s;

    YModemCb start_cb;
    YModemCb data_cb;
    YModemCb end_cb;
} YModem;

int ymodem_init(YModem *ymodem, uint8_t *buf, YModemPutc putc, YModemGetc getc,
                YModemCb start_cb, YModemCb data_cb, YModemCb end_cb);

int ymodem_download(YModem *ymodem, uint32_t timeout_s);

#endif
